unit battleventconditionsselection;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, Spin,
  EditBtn, ButtonPanel, fpjson, database;

type

  { TBattleEventConditionsSelectionForm }

  TBattleEventConditionsSelectionForm = class(TForm)
    ActorHpCheckBox: TCheckBox;
    ResultButtonPanel: TButtonPanel;
    SwitchIsOnLabel: TLabel;
    SwitchCheckBox: TCheckBox;
    SwitchEditButton: TEditButton;
    EnemyHpCheckBox: TCheckBox;
    EnemyHpComboBox: TComboBox;
    ActorHpComboBox: TComboBox;
    EnemyHpLessOfEqualLabel: TLabel;
    ActorHpLessOfEqualLabel: TLabel;
    EnemyHpPercentLabel: TLabel;
    ActorHpPercentLabel: TLabel;
    ActorHpSpinEdit: TSpinEdit;
    TurnNumberTimesXLabel: TLabel;
    TurnNumberPlusLabel: TLabel;
    TurnNumberConstSpinEdit: TSpinEdit;
    TurnEndsCheckBox: TCheckBox;
    TurnNumberCheckBox: TCheckBox;
    TurnNumberVarSpinEdit: TSpinEdit;
    EnemyHpSpinEdit: TSpinEdit;
    procedure ActorHpCheckBoxChange(Sender: TObject);
    procedure CancelButtonClick(Sender: TObject);
    procedure EnemyHpCheckBoxChange(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure OKButtonClick(Sender: TObject);
    procedure SwitchCheckBoxChange(Sender: TObject);
    procedure SwitchEditButtonButtonClick(Sender: TObject);
    procedure TurnNumberCheckBoxChange(Sender: TObject);
  private
    IsLoading: Boolean;
    ResultWasAccepted: Boolean;
    Db: TDatabase;
    Troop: TJSONObject;
    procedure PrefillData(Cond: TJSONObject);
    procedure UpdateSwitchDisplay;
    function MakeSelectedCondition: TJSONObject;
  public
    SelectedSwitch: Integer;
    SelectedCondition: TJSONObject;
    function ShowConditionSelector(Condition: TJSONObject; ATroop: TJSONObject; ADb: TDatabase): Boolean;
  end;

var
  BattleEventConditionsSelectionForm: TBattleEventConditionsSelectionForm;

implementation

uses
  namedindexselection, comboboxhelper;

{$R *.lfm}

{ TBattleEventConditionsSelectionForm }

procedure TBattleEventConditionsSelectionForm.OKButtonClick(Sender: TObject);
begin
  ResultWasAccepted := True;
  Close
end;

procedure TBattleEventConditionsSelectionForm.SwitchCheckBoxChange(
  Sender: TObject);
begin
  SwitchEditButton.Enabled := SwitchCheckBox.Checked;
end;

procedure TBattleEventConditionsSelectionForm.SwitchEditButtonButtonClick(
  Sender: TObject);
begin
  SelectedSwitch := NamedIndexSelectionForm.SelectSwitch(SelectedSwitch, Db);
  UpdateSwitchDisplay
end;

procedure TBattleEventConditionsSelectionForm.TurnNumberCheckBoxChange(
  Sender: TObject);
begin
  TurnNumberConstSpinEdit.Enabled := TurnNumberCheckBox.Checked;
  TurnNumberVarSpinEdit.Enabled := TurnNumberCheckBox.Checked
end;

procedure TBattleEventConditionsSelectionForm.ActorHpCheckBoxChange(
  Sender: TObject);
begin
  ActorHpComboBox.Enabled := ActorHpCheckBox.Checked;
  ActorHpSpinEdit.Enabled := ActorHpCheckBox.Checked
end;

procedure TBattleEventConditionsSelectionForm.CancelButtonClick(Sender: TObject
  );
begin
  ResultWasAccepted := False;
  Close
end;

procedure TBattleEventConditionsSelectionForm.EnemyHpCheckBoxChange(
  Sender: TObject);
begin
  EnemyHpComboBox.Enabled := EnemyHpCheckBox.Checked;
  EnemyHpSpinEdit.Enabled:= EnemyHpCheckBox.Checked
end;

procedure TBattleEventConditionsSelectionForm.FormDestroy(Sender: TObject);
begin
  if SelectedCondition <> nil then
    SelectedCondition.Free;
end;

procedure TBattleEventConditionsSelectionForm.PrefillData(Cond: TJSONObject);
  procedure PrefillCheckbox(Checkbox: TCheckBox; VarName: String);
  var
    IsValid: Boolean = False;
    IsValidJson: TJSONBoolean;
  begin
    if (Cond <> nil) and Cond.Find(VarName, IsValidJson) then
      IsValid := IsValidJson.AsBoolean;
    Checkbox.Checked := IsValid;
  end;

  procedure PrefillHp(Spin: TSpinEdit; VarName: String);
  var
    Hp: Integer = 0;
    HpJson: TJSONNumber;
  begin
    if (Cond <> nil) and Cond.Find(VarName, HpJson) then
      Hp := HpJson.AsInteger;
    Spin.Value := Hp;
  end;

  procedure PrefillEnemyIndex;
  var
    Index: Integer = 0;
    IndexJson: TJSONNumber;
  begin
    if (Cond <> nil) and Cond.Find('enemyIndex', IndexJson) then
      Index := IndexJson.AsInteger;
    EnemyHpComboBox.ItemIndex := Index;
  end;

  procedure PrefillActorId;
  var
    Id: Integer = 0;
    IdJson: TJSONNumber;
  begin
    if (Cond <> nil) and Cond.Find('actorId', IdJson) then
      Id := IdJson.AsInteger;
    ActorHpComboBox.ItemIndex := Id - 1;
  end;

  procedure PrefillTurnNumber;
  var
    ConstVal: Integer = 0;
    VarVal: Integer = 0;
    ConstVarJson, VarValJson: TJSONNumber;
  begin
    if (Cond <> nil) and Cond.Find('turnA', ConstVarJson) then
      ConstVal := ConstVarJson.AsInteger;
    if (Cond <> nil) and Cond.Find('turnB', VarValJson) then
      VarVal := VarValJson.AsInteger;

    TurnNumberConstSpinEdit.Value := ConstVal;
    TurnNumberVarSpinEdit.Value := VarVal;
  end;

  procedure PrefillSwitch;
  var
    SwitchIdJson: TJSONNumber;
  begin
    SelectedSwitch := 1;
    if (Cond <> nil) and Cond.Find('switchId', SwitchIdJson) then
      SelectedSwitch := SwitchIdJson.AsInteger;
    UpdateSwitchDisplay;
  end;

begin
  IsLoading := True;

  PrefillCheckbox(TurnEndsCheckBox, 'turnEnding');

  PrefillCheckbox(TurnNumberCheckBox, 'turnValid');
  PrefillTurnNumber;

  PrefillCheckbox(EnemyHpCheckBox, 'enemyValid');
  PrefillEnemyIndex;
  PrefillHp(EnemyHpSpinEdit, 'enemyHp');

  PrefillCheckbox(ActorHpCheckBox, 'actorValid');
  PrefillActorId;
  PrefillHp(ActorHpSpinEdit, 'actorHp');

  PrefillCheckbox(SwitchCheckBox, 'switchValid');
  PrefillSwitch;

  IsLoading := False;
end;

procedure TBattleEventConditionsSelectionForm.UpdateSwitchDisplay;
begin
  SwitchEditButton.Text := Db.GetSwitchName(SelectedSwitch);
end;

function TBattleEventConditionsSelectionForm.MakeSelectedCondition: TJSONObject;
begin
  MakeSelectedCondition := TJSONObject.Create([
    'actorHp', ActorHpSpinEdit.Value,
    'actorId', ActorHpComboBox.ItemIndex + 1,
    'actorValid', ActorHpCheckBox.Checked,
    'enemyHp', EnemyHpSpinEdit.Value,
    'enemyIndex', EnemyHpComboBox.ItemIndex,
    'enemyValid', EnemyHpCheckBox.Checked,
    'switchId', SelectedSwitch,
    'switchValid', SwitchCheckBox.Checked,
    'turnA', TurnNumberConstSpinEdit.Value,
    'turnB', TurnNumberVarSpinEdit.Value,
    'turnEnding', TurnEndsCheckBox.Checked,
    'turnValid', TurnNumberCheckBox.Checked
  ]);
end;

function TBattleEventConditionsSelectionForm.ShowConditionSelector(
  Condition: TJSONObject; ATroop: TJSONObject; ADb: TDatabase): Boolean;

  procedure FillTroopComboBox;
  var
    I: Integer;
    Members: TJSONArray;
  begin
    Members := ATroop.Arrays['members'];
    with EnemyHpComboBox.Items do begin
      BeginUpdate;
      Clear;
      for I := 0 to 7 do begin
        if I < Members.Count then
          Add(Format('#%d %s', [I+1, Db.GetEnemyName(Members.Objects[I].Integers['enemyId'], False)]))
        else
          Add('#' + IntToStr(I+1));
      end;
      EndUpdate;
    end;
  end;

begin
  Db := ADb;
  Troop := ATroop;
  ResultWasAccepted := False;

  FillTroopComboBox;
  FillDbArrayComboBox(ActorHpComboBox, Db.Actors);

  PrefillData(Condition);
  ShowModal;
  if SelectedCondition <> nil then begin
    SelectedCondition.Free;
    SelectedCondition := nil
  end;
  SelectedCondition := MakeSelectedCondition;

  ActorHpComboBox.Items.Clear;
  EnemyHpComboBox.Items.Clear;

  ShowConditionSelector := ResultWasAccepted
end;

end.

